
#include "tcp_packet.h"
#include "endian_portable.h"
#include "IPLayer.h"
#include "IPv4Layer.h"
#include "IPv6Layer.h"
#include "TcpLayer.h"
#include "log/log.h"
#include "PacketUtils.h"
#include "SystemUtils.h"
#include "TcpLayer.h"
#include "TimespecTimeval.h"
#include "session_timer.h"

#define SEQ_LT(a, b) ((int32_t)((a) - (b)) < 0)
#define SEQ_LEQ(a, b) ((int32_t)((a) - (b)) <= 0)
#define SEQ_GT(a, b) ((int32_t)((a) - (b)) > 0)
#define SEQ_GEQ(a, b) ((int32_t)((a) - (b)) >= 0)
#define SEQ_EQ(a, b) ((a) == (b))

namespace secsmart_tcpip
{
#ifdef LIBDEBUG
int g_tcp_stream_new_num = 0;
int g_tcp_stream_delete_num = 0;
#endif

// 构造缓存数据
tcp_segment::tcp_segment(tcphdr *hdr, packet_meta_t *meta, int pre_overlap_len, int next_overlap_len)
{
    uint16_t tcp_hdr_len = uint16_t(hdr->dataOffset * 4);
    uint16_t data_len = uint16_t(meta->l4_payload_len - pre_overlap_len - next_overlap_len);
    uint16_t pkt_len = uint16_t(meta->ip_hdr_len + tcp_hdr_len + data_len);

    this->pkt = new uint8_t[pkt_len];
    if (this->pkt == nullptr) {
        return;
    }
    this->data_len = data_len;
    this->seq = be32toh(hdr->sequenceNumber) + pre_overlap_len;
    this->ack = be32toh(hdr->ackNumber);
    this->timestamp = meta->timestamp;
    this->data_offset = uint16_t(meta->ip_hdr_len + tcp_hdr_len);

    // 拷贝报文
    if (pre_overlap_len == 0) {
        memcpy(this->pkt, (uint8_t *)hdr - meta->ip_hdr_len, pkt_len);
    } else {
        // 先拷贝ip头和tcp头
        memcpy(this->pkt, (uint8_t *)hdr - meta->ip_hdr_len, this->data_offset);
        // 再拷贝数据
        memcpy(this->pkt + this->data_offset, (uint8_t *)hdr + tcp_hdr_len + pre_overlap_len, meta->l4_payload_len);

        // 修改缓存报文中的seq
        tcphdr *seg_tcp_hdr = (tcphdr *)(this->pkt + meta->ip_hdr_len);
        seg_tcp_hdr->sequenceNumber = htobe32(this->seq);
    }

    if (pre_overlap_len != 0 || next_overlap_len != 0) {
        // 修改报文ip报文的长度字段
        if (meta->ip_version == 4) {
            iphdr *seg_ip_hdr = (iphdr *)(this->pkt);
            seg_ip_hdr->totalLength = uint16_t(seg_ip_hdr->totalLength - pre_overlap_len - next_overlap_len);
        } else {
            ip6_hdr *seg_ip6_hdr = (ip6_hdr *)(this->pkt);
            seg_ip6_hdr->payloadLength = uint16_t(seg_ip6_hdr->payloadLength - pre_overlap_len - next_overlap_len);
        }
    }
}

tcp_segment::~tcp_segment()
{
    if (pkt != NULL) {
        delete[] pkt;
    }
}

tcp_hstream::tcp_hstream()
{
    state = TCP_HALF_STREAM_INIT;
    rcv_fin = 0;
    to_server = 0;
    seg_num = 0;
}

TcpPacketHandler::TcpPacketHandler()
{
    // 设置默认配置
    m_cfg.pkt_reassemble_enable = true;
    m_cfg.pkt_stat_enable = true;
    m_cfg.work_mode = TCP_REASSEMBLY_MODE_NORMAL;
    m_cfg.max_stream_num = 100 * 1024;     // tcp连接的规格(默认100K)
    m_cfg.max_seg_cache_num = 100 * 1024; // 分片缓存最大数量（默认100K），超过缓存数量，不缓存直接转发
    m_cfg.max_seg_cache_per_stream = 32;  // 每条连接的最大缓存分段数（默认32）
    m_cfg.stream_timeout = 600 * 1000;    // tcp连接老化超时时间,单位毫秒（默认600秒 10分钟）
    m_cfg.seg_cache_timeout = 60 * 1000;  // 缓存超时时间，单位毫秒
    m_cfg.aging_proc_interval = 1 * 1000; // 老化执行时间，有报文每隔1秒(1000毫秒)执行一遍老化。
    m_cfg.aging_proc_once_num = 100;      // 一次处理的老化节点数。

    // 统计清零
    m_stat.clear();

    // 回调清零
    m_tcp_event_cb.tcp_conn_event_start = nullptr;
    m_tcp_event_cb.tcp_conn_event_end = nullptr;
    m_tcp_event_cb.tcp_conn_event_rcv_data = nullptr;
    m_tcp_event_cb.tcp_conn_event_rcv_ctrl_pkt = nullptr;
    m_user_data = nullptr;

    m_aging_last_proc_time = 0; // 上次老化处理时间
}

TcpPacketHandler::~TcpPacketHandler() { del_all_tcp_streams(); }

void TcpPacketHandler::register_tcp_conn_event_cb(tcp_conn_event_cb_t cb, void *user_data)
{
    m_tcp_event_cb = cb;
    m_user_data = user_data;
}

uint32_t TcpPacketHandler::process_packet(uint8_t *tcp_hdr, packet_meta_t *meta)
{
    if (meta == nullptr) {
        return TCP_PKT_ERR;
    }

    // 报文统计
    m_stat.pkt_rcv_num++;
    m_stat.pkt_rcv_data_bytes += meta->pkt_len;

    // 老化处理
    uint64_t now = SessionTimer::get_tick();
    if (m_aging_last_proc_time + m_cfg.aging_proc_interval <= now) {
        aging_proc();
        m_aging_last_proc_time = now;
    }

    // Ignore non-TCP packets
    if (meta->ip_protocol != PACKETPP_IPPROTO_TCP) {
        m_stat.pkt_not_tcp_num++;
        return TCP_PKT_ERR;
    }

    // 纯ack报文不处理
    tcphdr *hdr = (tcphdr *)tcp_hdr;
    if (hdr->ackFlag && (hdr->synFlag + hdr->rstFlag + hdr->finFlag == 0) && (meta->l4_payload_len == 0)) {
        m_stat.pkt_no_data_num++;
        return TCP_PKT_OK;
    }

    // tcp 报文类型统计
    if (hdr->synFlag) {
        m_stat.pkt_syn_num++;
    }

    if (hdr->finFlag) {
        m_stat.pkt_fin_num++;
    }

    if (hdr->rstFlag) {
        m_stat.pkt_rst_num++;
    }

    // 报文处理
    // 1.报文没有命中db server，先根据端口和ip地址临时设置方向
    if (meta->direction == PKT_DIRECTION_UNKNOW) {
        if ((meta->dport < meta->sport) || ((meta->dport == meta->sport) && (meta->dip < meta->sip))) {
            meta->direction = PKT_DIRECTION_CLIENT_TO_SERVER;
        } else {
            meta->direction = PKT_DIRECTION_SERVER_TO_CLIENT;
        }
        m_stat.pkt_not_server_num++;
    }

    // 2.获取tcp stream
    uint32_t ret;
    tcp_stream_id_t id;
    get_tcp_streamid(meta, id);
    tcp_stream_sptr stream = get_tcp_stream(id);

    // 3.报文处理
    if (stream == NULL) { // 新的连接，进入首包处理流程
        ret = first_pkt_proc(hdr, meta, id);
    } else { // 连接已经存在，进入后续包处理流程
        ret = subsequent_pkt_proc(stream, hdr, meta);
    }
    if (ret == TCP_PKT_ERR) {
        m_stat.pkt_drop_num++;
    }

    return ret;
}

void TcpPacketHandler::close_tcp_stream(tcp_stream_id_t &id)
{
    del_tcp_stream(id, TCP_STREAM_CLOSE_MANUALLY);
}

void TcpPacketHandler::close_all_tcp_streams()
{
    del_all_tcp_streams();
}

bool TcpPacketHandler::is_stream_open(const tcp_stream_id_t &id)
{
    auto mapIter = m_tcp_stream_map.find(id);
    if (mapIter == m_tcp_stream_map.end()) {
        return false;
    }
    return true;
}

// 根据报文信息构建tcp连接ID
void TcpPacketHandler::get_tcp_streamid(packet_meta_t *meta, tcp_stream_id_t &id)
{
    id.source = meta->source;
    if (meta->is_vxlan) {
        id.vlanid = meta->vni;
    } else {
        id.vlanid = meta->vlanid;
    }

    if (meta->direction == PKT_DIRECTION_CLIENT_TO_SERVER) {
        id.sip = meta->sip;
        id.sport = meta->sport;
        id.dip = meta->dip;
        id.dport = meta->dport;
    } else { // meta->direction == PKT_DIRECTION_SERVER_TO_CLIENT
        id.sip = meta->dip;
        id.sport = meta->dport;
        id.dip = meta->sip;
        id.dport = meta->sport;
    }
}

uint32_t TcpPacketHandler::first_pkt_proc(tcphdr *hdr, packet_meta_t *meta, tcp_stream_id_t &id)
{
    if (hdr->finFlag || hdr->rstFlag) {
        return TCP_PKT_ERR;
    }

    tcp_stream_sptr stream = add_tcp_stream(id, hdr, meta);
    if (stream == nullptr) {
        return TCP_PKT_ERR;
    }

    stream->statistic.pkt_rcv_num++;
    stream->statistic.pkt_rcv_data_bytes += meta->l4_payload_len;

    if (meta->l4_payload_len > 0) {
        tcp_hstream_t *snd = NULL;
        tcp_hstream_t *rcv = NULL;
        if (meta->direction == PKT_DIRECTION_CLIENT_TO_SERVER) {
            snd = &(stream->client);
            rcv = &(stream->server);
        } else {
            snd = &(stream->server);
            rcv = &(stream->client);
        }
        if (m_cfg.pkt_reassemble_enable == false) {
            return tcp_stream_data_proc_no_reassemble(stream, snd, rcv, hdr, meta);
        } else {
            return tcp_stream_data_proc(stream, snd, rcv, hdr, meta);
        }
    }
    return TCP_PKT_OK;
}

uint32_t TcpPacketHandler::subsequent_pkt_proc(tcp_stream_sptr stream, tcphdr *hdr, packet_meta_t *meta)
{
    tcp_hstream_t *snd = NULL;
    tcp_hstream_t *rcv = NULL;
    if (meta->direction == PKT_DIRECTION_CLIENT_TO_SERVER) {
        snd = &(stream->client);
        rcv = &(stream->server);
    } else {
        snd = &(stream->server);
        rcv = &(stream->client);
    }

    stream->statistic.pkt_rcv_num++;
    stream->statistic.pkt_rcv_data_bytes += meta->l4_payload_len;

    switch (snd->state) {
        case TCP_HALF_STREAM_INIT:
            return half_stream_init_state_proc(stream, snd, rcv, hdr, meta);
        case TCP_HALF_STREAM_SYN_SENT:
            return half_stream_syn_state_proc(stream, snd, rcv, hdr, meta);
        case TCP_HALF_STREAM_PRE_ESTABLISHED:
            return half_stream_preest_state_proc(stream, snd, rcv, hdr, meta);
        case TCP_HALF_STREAM_ESTABLISHED:
            return half_stream_est_state_proc(stream, snd, rcv, hdr, meta);
        case TCP_HALF_STREAM_FIN:
            return half_stream_fin_state_proc(stream, snd, rcv, hdr, meta);
        case TCP_HALF_STREAM_CLOSE:
            return half_stream_close_state_proc(stream, snd, rcv, hdr, meta);
        default:
            break;
    }
    return TCP_PKT_ERR;
}

uint32_t TcpPacketHandler::half_stream_init_state_proc(tcp_stream_sptr stream, tcp_hstream_t *snd, tcp_hstream_t *rcv,
                                                       tcphdr *hdr, packet_meta_t *meta)
{
    if (hdr->rstFlag) {
        del_tcp_stream(stream->id, TCP_STREAM_CLOSE_RST);
        return TCP_PKT_OK;
    }

    if (hdr->finFlag) {
        del_tcp_stream(stream->id, TCP_STREAM_CLOSE_FIN);
        return TCP_PKT_OK;
    }

    if (hdr->synFlag || (m_cfg.work_mode == TCP_REASSEMBLY_MODE_FAST)) {
        snd->seq = be32toh(hdr->sequenceNumber) + hdr->synFlag;
        if (hdr->ackFlag) {
            rcv->seq = be32toh(hdr->ackNumber);
        }
        snd->state = TCP_HALF_STREAM_ESTABLISHED;
        rcv->state = TCP_HALF_STREAM_ESTABLISHED;
        stream->status = TCP_STREAM_ESTABLISHED;
        tcp_stream_start(stream);
        flush_cached_tcp_segment(stream);
        if (hdr->synFlag) {
            tcp_stream_rcv_ctrl_pkt(stream, hdr, meta);
        }
    }

    if (meta->l4_payload_len > 0) {
        return tcp_stream_data_proc(stream, snd, rcv, hdr, meta);
    }

    return TCP_PKT_OK;
}

uint32_t TcpPacketHandler::half_stream_syn_state_proc(tcp_stream_sptr stream, tcp_hstream_t *snd, tcp_hstream_t *rcv,
                                                      tcphdr *hdr, packet_meta_t *meta)
{
    if (hdr->rstFlag) {
        del_tcp_stream(stream->id, TCP_STREAM_CLOSE_RST);
        return TCP_PKT_OK;
    }

    if (hdr->finFlag) {
        del_tcp_stream(stream->id, TCP_STREAM_CLOSE_FIN);
        return TCP_PKT_OK;
    }

    if (hdr->synFlag) {
        m_stat.pkt_rtns_num++;
        stream->statistic.pkt_rtns_num++;
        return TCP_PKT_ERR;
    }

    if (SEQ_EQ(be32toh(hdr->sequenceNumber), snd->seq)) { // 发送数据报文(反向syn报文丢失)，状态切换为established
        rcv->seq = be32toh(hdr->ackNumber);
        snd->state = rcv->state = TCP_HALF_STREAM_ESTABLISHED;
        stream->status = TCP_STREAM_ESTABLISHED;
        tcp_stream_start(stream);
        flush_cached_tcp_segment(stream);
    }

    if (meta->l4_payload_len > 0) {
        return tcp_stream_data_proc(stream, snd, rcv, hdr, meta);
    }

    return TCP_PKT_OK;
}

uint32_t TcpPacketHandler::half_stream_est_state_proc(tcp_stream_sptr stream, tcp_hstream_t *snd, tcp_hstream_t *rcv,
                                                      tcphdr *hdr, packet_meta_t *meta)
{
    uint32_t ret = TCP_PKT_OK;
    if (hdr->synFlag && m_cfg.pkt_reassemble_enable) {
        m_stat.pkt_ooo_num++;
        stream->statistic.pkt_ooo_num++;
        return TCP_PKT_ERR;
    }

    if (hdr->rstFlag) {
        del_tcp_stream(stream->id, TCP_STREAM_CLOSE_RST);
        return TCP_PKT_OK;
    }

    if (meta->l4_payload_len > 0) {
        if (m_cfg.pkt_reassemble_enable == false) {
            ret = tcp_stream_data_proc_no_reassemble(stream, snd, rcv, hdr, meta);
        } else {
            ret = tcp_stream_data_proc(stream, snd, rcv, hdr, meta);
        }
    }

    // tcp fin 处理
    if (hdr->finFlag) {
        snd->rcv_fin = true;
        snd->fin_seq = be32toh(hdr->sequenceNumber);
    }
    if (m_cfg.pkt_reassemble_enable == false)  {
        if (snd->rcv_fin && rcv->rcv_fin) {
            del_tcp_stream(stream->id, TCP_STREAM_CLOSE_FIN);
        }
    } else if (snd->rcv_fin && SEQ_LEQ(snd->fin_seq, snd->seq)) {
        snd->state = TCP_HALF_STREAM_FIN;
        if (rcv->state == TCP_HALF_STREAM_FIN) {
            del_tcp_stream(stream->id, TCP_STREAM_CLOSE_FIN);
        }
    }

    return ret;
}

uint32_t TcpPacketHandler::half_stream_preest_state_proc(tcp_stream_sptr stream, tcp_hstream_t *snd, tcp_hstream_t *rcv,
                                                         tcphdr *hdr, packet_meta_t *meta)
{
    uint32_t ret = TCP_PKT_OK;
    if (hdr->rstFlag) {
        del_tcp_stream(stream->id, TCP_STREAM_CLOSE_RST);
        return ret;
    }

    if (hdr->synFlag) { // 收到syn报文
        if (hdr->ackFlag == 0) { 
            if (meta->hit_server == 0 && meta->direction == PKT_DIRECTION_SERVER_TO_CLIENT) {
                stream->reversed = true;
            }
        } else { // syn-ack
            if (meta->hit_server == 0 && meta->direction == PKT_DIRECTION_CLIENT_TO_SERVER) {
                stream->reversed = true;
            }
        }
        stream->rcv_syn = true;
        snd->seq = be32toh(hdr->sequenceNumber);
        snd->state = TCP_HALF_STREAM_SYN_SENT;
        if (rcv->state == TCP_HALF_STREAM_SYN_SENT) {
            snd->state = rcv->state = TCP_HALF_STREAM_ESTABLISHED;
            stream->status = TCP_STREAM_ESTABLISHED;
        } else if (hdr->ackFlag) {
            rcv->seq = be32toh(hdr->ackNumber);
            snd->state = rcv->state = TCP_HALF_STREAM_ESTABLISHED;
            stream->status = TCP_STREAM_ESTABLISHED;
        }
        if (stream->status == TCP_STREAM_ESTABLISHED) {
            tcp_stream_start(stream);
            flush_cached_tcp_segment(stream);
        }

        tcp_stream_rcv_ctrl_pkt(stream, hdr, meta);
        return ret;
    }

    // 数据报文缓存
    if (meta->l4_payload_len > 0) {
        ret = tcp_stream_data_proc(stream, snd, rcv, hdr, meta);
    }

    // fin 报文处理
    if (hdr->finFlag) {
        snd->rcv_fin = true;
        snd->fin_seq = be32toh(hdr->sequenceNumber);
    }

    // 收到fin报文，或已经缓存了6个分段了，认为前面tcp握手已经丢失，数据需要马上上送
    if (snd->rcv_fin || snd->seg_num + rcv->seg_num >= 6) {
        snd->seq = snd->seg_list.empty() ? rcv->seg_list.front()->ack : snd->seg_list.front()->seq;
        rcv->seq = rcv->seg_list.empty() ? snd->seg_list.front()->ack : rcv->seg_list.front()->seq;
        snd->state = rcv->state = TCP_HALF_STREAM_ESTABLISHED;
        stream->status = TCP_STREAM_ESTABLISHED;
        tcp_stream_start(stream);
        flush_cached_tcp_segment(stream);
    }

    if (snd->rcv_fin && SEQ_LEQ(snd->fin_seq, snd->seq)) {
        snd->state = TCP_HALF_STREAM_FIN;
        if (rcv->state == TCP_HALF_STREAM_FIN) {
            del_tcp_stream(stream->id, TCP_STREAM_CLOSE_FIN);
        }
    }

    return ret;
}

uint32_t TcpPacketHandler::half_stream_fin_state_proc(tcp_stream_sptr stream, tcp_hstream_t *snd, tcp_hstream_t *rcv,
                                                      tcphdr *hdr, packet_meta_t *meta)
{
    (void)snd;
    (void)rcv;
    (void)meta;

    if (hdr->rstFlag) {
        del_tcp_stream(stream->id, TCP_STREAM_CLOSE_RST);
        return TCP_PKT_OK;
    }

    return TCP_PKT_ERR;
}

uint32_t TcpPacketHandler::half_stream_close_state_proc(tcp_stream_sptr stream, tcp_hstream_t *snd, tcp_hstream_t *rcv,
                                                        tcphdr *hdr, packet_meta_t *meta)
{
    (void)stream;
    (void)snd;
    (void)rcv;
    (void)hdr;
    (void)meta;
    return TCP_PKT_ERR;
}

uint32_t TcpPacketHandler::tcp_stream_data_proc(tcp_stream_sptr stream, tcp_hstream_t *snd, tcp_hstream_t *rcv,
                                                tcphdr *hdr, packet_meta_t *meta)
{
    uint32_t data_len = meta->l4_payload_len;
    uint32_t hdr_len = hdr->dataOffset * 4;
    uint32_t seq = be32toh(hdr->sequenceNumber);
    uint32_t ack = be32toh(hdr->ackNumber);

    bool to_server = stream->reversed ? (!(bool)(snd->to_server)) : ((bool)(snd->to_server));
    if (to_server) {
        LOG_DEBUG("Rcv client pkt[seq:{} dataLen:{}], Client seq:{} Server seq:{}", seq, data_len, snd->seq, rcv->seq);
    } else {
        LOG_DEBUG("Rcv client pkt[seq:{} dataLen:{}], Client seq:{} Server seq:{}", seq, data_len, rcv->seq, snd->seq);
    }

    if (snd->state != TCP_HALF_STREAM_ESTABLISHED) {
        // 缓存数据
        LOG_DEBUG("The state of connection not estabished, cache tcp segment.");
        return cache_tcp_segment(stream, snd, hdr, meta);
    }

    if (SEQ_LEQ(seq + data_len, snd->seq)) { // 重传报文
        LOG_DEBUG("The packet is a retransmit packet.");
        m_stat.pkt_rtns_num++;
        stream->statistic.pkt_rtns_num++;
        return TCP_PKT_ERR;
    } else if (SEQ_GT(seq, snd->seq)) { // 后续报文先到
        return cache_tcp_segment(stream, snd, hdr, meta);
    }

    // rcv 方向上报文还没来，snd的报文提前到达有乱序或丢包（大概率是丢包）
    if (SEQ_GT(ack, rcv->seq)) {
        m_stat.pkt_two_way_ooo_num++;
        stream->statistic.pkt_two_way_ooo_num++;
        if (m_cfg.work_mode == TCP_REASSEMBLY_MODE_FAST) {
            // 快速模式按照丢包处理
            flush_cached_tcp_segment_oneway(stream, rcv, snd, true);
        } else {
            // 普通模式按乱序处理
            return cache_tcp_segment(stream, snd, hdr, meta);
        }
    }

    // 将数据提交给上层业务
    int valid_data_len = seq + data_len - snd->seq;
    uint8_t *data = (uint8_t *)hdr + hdr_len + data_len - valid_data_len;
    int rcv_missing_bytes = (int)(ack - rcv->seq);

    tcp_stream_data_t stream_data;
    stream_data.data = data;
    stream_data.data_len = valid_data_len;
    stream_data.data_offset = meta->l4_offset - meta->ip_offset + hdr_len + data_len - valid_data_len;
    stream_data.rcv_missing_bytes = rcv_missing_bytes;
    stream_data.snd_missing_bytes = 0;
    stream_data.timestamp = meta->timestamp;
    stream_data.is_forward = to_server;
    tcp_stream_rcv_data(stream, stream_data);

    rcv->seq = ack;
    snd->seq += valid_data_len;
    m_stat.pkt_in_order_num++;
    stream->statistic.pkt_in_order_num++;

    // 刷新缓存队列
    if (stream->cache_flag) {
        flush_cached_tcp_segment(stream);
    }
    return TCP_PKT_OK;
}

uint32_t TcpPacketHandler::tcp_stream_data_proc_no_reassemble(tcp_stream_sptr stream, tcp_hstream_t *snd,
                                                              tcp_hstream_t *rcv, tcphdr *hdr, packet_meta_t *meta)
{
    (void)rcv;
    uint32_t data_len = meta->l4_payload_len;
    uint32_t hdr_len = hdr->dataOffset * 4;
    
    bool to_server = stream->reversed ? (!(bool)(snd->to_server)) : ((bool)(snd->to_server));
    uint8_t *data = (uint8_t *)hdr + hdr_len;

    // 将数据提交给上层业务
    tcp_stream_data_t stream_data;
    stream_data.data = data;
    stream_data.data_len = data_len;
    stream_data.data_offset = meta->l4_offset - meta->ip_offset + hdr_len;
    stream_data.rcv_missing_bytes = 0;
    stream_data.snd_missing_bytes = 0;
    stream_data.timestamp = meta->timestamp;
    stream_data.is_forward = to_server;
    tcp_stream_rcv_data(stream, stream_data);
    return TCP_PKT_OK;
}

uint32_t TcpPacketHandler::cache_tcp_segment(tcp_stream_sptr stream, tcp_hstream_t *snd, tcphdr *hdr,
                                             packet_meta_t *meta)
{
    uint32_t pkt_seq = be32toh(hdr->sequenceNumber);
    size_t data_len = meta->l4_payload_len;
    int pre_overlap_len = 0;
    int next_overlap_len = 0;

    // 查找插入点 hdr->seq 在链中的位置
    std::list<tcp_segment_t *> *list = &snd->seg_list;
    std::list<tcp_segment_t *>::iterator pos = snd->seg_list.begin();
    tcp_segment_t *pre = NULL, *next = NULL;
    for (; pos != list->end(); pos++) {
        if (SEQ_GEQ((*pos)->seq, pkt_seq)) { // 节点的序列号>=当前报文的序列号
            next = *pos;
            break;
        }
        pre = *pos;
    }

    if (next != NULL) { // 查找hdr->seq + dataLen在链中的位置,删除内容重复的分段
        for (; pos != list->end();) {
            if (SEQ_GEQ((*pos)->seq + (*pos)->data_len, pkt_seq + data_len)) {
                next = *pos;
                break;
            }
            delete *pos;
            pos = list->erase(pos);
            snd->seg_num--;
            m_stat.pkt_cache_num--;
        }
    }

    // 和前一块的关系
    uint32_t new_seq = pkt_seq;
    if (pre != NULL) {
        if (SEQ_GEQ(pre->seq + pre->data_len, pkt_seq + data_len)) { // 被包含关系
            m_stat.pkt_rtns_num++;
            stream->statistic.pkt_rtns_num++;
            return TCP_PKT_ERR;
        } else if (SEQ_GT(pre->seq + pre->data_len, pkt_seq)) { // 重叠关系
            new_seq = pre->seq + (uint32_t)pre->data_len;
            pre_overlap_len = new_seq - pkt_seq;
        } else { // 没有交叉重叠
            // 不用处理
        }
    }

    // 和后一块的关系（被包含/包含/重叠/没有交叉重叠，其中包含有可能包含多个后续段）
    // 前面处理时，内容重复的分段已经被删除，故这里不存在当前分片包含后续分片的情况
    if (next != NULL) {
        if (SEQ_EQ(new_seq, next->seq)) { // 被包含
            m_stat.pkt_rtns_num++;
            stream->statistic.pkt_rtns_num++;
            return TCP_PKT_ERR;
        } else if (SEQ_GT(pkt_seq + data_len, next->seq)) { // 重叠
            next_overlap_len = int(pkt_seq + data_len - next->seq);
        } else { // 没有重叠
            // 不用处理
        }
    }

    m_stat.pkt_ooo_num++; // 需要进行缓存的认为都是乱序报文
    stream->statistic.pkt_ooo_num++;

    // 申请节点
    tcp_segment_t *segment = new tcp_segment_t(hdr, meta, pre_overlap_len, next_overlap_len);
    if (segment == nullptr || segment->pkt == nullptr) {
        m_stat.pkt_cache_fail_num++;
        stream->statistic.pkt_cache_fail_num++;
        delete segment;
        return TCP_PKT_ERR;
    }

    list->insert(pos, segment);
    snd->seg_num++;
    m_stat.pkt_cache_num++;

    bool to_server = stream->reversed ? (!(bool)(snd->to_server)) : ((bool)(snd->to_server));
    if (to_server) {
        LOG_DEBUG("Cache Client Data. data[seq:{} len:{}], cur cache pkt num:{}",
            segment->seq, segment->data_len, snd->seg_num);
    } else {
        LOG_DEBUG("Cache Server Data. data[seq:{} len:{}], cur cache pkt num:{}",
            segment->seq, segment->data_len, snd->seg_num);
    }

    if (!stream->cache_flag) {
        stream->cache_flag = true;
        tcp_stream_update_timer(stream);
    }

    if (stream->client.seg_num + stream->server.seg_num > m_cfg.max_seg_cache_per_stream) { // 分片缓存超过单条流的规格
        m_stat.pkt_cache_over_stream_spec_num++;
        del_one_cached_segment(stream);
    }

    if (m_stat.pkt_cache_num > m_cfg.max_seg_cache_num) { // 分片缓存超过整机规格
        m_stat.pkt_cache_over_spec_num++;
        del_one_cached_segment(stream);
    }

    return TCP_PKT_CACHE;
}

// 当force为true时，明确发送方有丢包，不再比较发送方的序列号。
uint32_t TcpPacketHandler::flush_cached_tcp_segment_oneway(tcp_stream_sptr stream, tcp_hstream_t *snd,
                                                           tcp_hstream_t *rcv, bool force)
{
    uint32_t count = 0;
    std::list<tcp_segment_t *>::iterator iter = snd->seg_list.begin();
    tcp_segment_t *segment = NULL;
    bool to_server = stream->reversed ? (!(bool)(snd->to_server)) : ((bool)(snd->to_server));

    while (iter != snd->seg_list.end()) {
        segment = *iter;
        if ((SEQ_EQ(segment->seq, snd->seq) || force) && SEQ_LEQ(segment->ack, rcv->seq)) {
            int snd_missing_bytes = (int)(segment->seq - snd->seq);
            tcp_stream_data_t stream_data;
            stream_data.data = segment->pkt + segment->data_offset;
            stream_data.data_len = segment->data_len;
            stream_data.data_offset = segment->data_offset;
            stream_data.rcv_missing_bytes = 0;
            stream_data.snd_missing_bytes = snd_missing_bytes;
            stream_data.timestamp = segment->timestamp;
            stream_data.is_forward = to_server;
            tcp_stream_rcv_data(stream, stream_data);

            snd->seq = segment->seq + (uint32_t)segment->data_len;
            delete segment;
            iter = snd->seg_list.erase(iter);
            snd->seg_num--;
            m_stat.pkt_cache_num--;
            count++;
        } else {
            break;
        }
    };
    return count;
}

void TcpPacketHandler::flush_cached_tcp_segment(tcp_stream_sptr stream)
{
    if (stream->client.seg_list.empty() && stream->server.seg_list.empty()) {
        return;
    }

    uint32_t count = 0;
    do {
        flush_cached_tcp_segment_oneway(stream, &stream->client, &stream->server);
        count = flush_cached_tcp_segment_oneway(stream, &stream->server, &stream->client);
    } while (count != 0);

    if ((stream->client.seg_list.empty()) && (stream->server.seg_list.empty())) {
        stream->cache_flag = false;
    }
}

void TcpPacketHandler::del_one_cached_segment(tcp_stream_sptr stream)
{
    tcp_segment_t *client_seg = NULL;
    tcp_segment_t *server_seg = NULL;
    if (!stream->client.seg_list.empty()) {
        client_seg = stream->client.seg_list.front();
    }
    if (!stream->server.seg_list.empty()) {
        server_seg = stream->server.seg_list.front();
    }
    if ((client_seg == NULL) && (server_seg == NULL)) {
        return;
    }

    // 将状态切换为TCP_STREAM_ESTABLISHED
    if (stream->status < TCP_STREAM_ESTABLISHED) {
        if (stream->client.state != TCP_HALF_STREAM_SYN_SENT) {
            stream->client.seq = (client_seg != NULL) ? client_seg->seq : server_seg->ack;
        }
        if (stream->server.state != TCP_HALF_STREAM_SYN_SENT) {
            stream->server.seq = (server_seg != NULL) ? server_seg->seq : client_seg->ack;
        }
        stream->client.state = stream->server.state = TCP_HALF_STREAM_ESTABLISHED;
        stream->status = TCP_STREAM_ESTABLISHED;
        tcp_stream_start(stream);
    }

    // 优先发送客户端报文
    tcp_hstream_t *snd = &(stream->client);
    tcp_hstream_t *rcv = &(stream->server);
    tcp_segment_t *segment = client_seg;
    if ((client_seg == NULL) || ((server_seg != NULL) && SEQ_GT(client_seg->ack, server_seg->seq))) {
        snd = &(stream->server);
        rcv = &(stream->client);
        segment = server_seg;
    }

    int snd_miss_len = segment->seq - snd->seq;
    int rcv_miss_len = 0;
    if (SEQ_GT(segment->ack, rcv->seq)) {
        rcv_miss_len = segment->ack - rcv->seq;
    }

    bool to_server = stream->reversed ? (!(bool)(snd->to_server)) : ((bool)(snd->to_server));
    tcp_stream_data_t stream_data;
    stream_data.data = segment->pkt + segment->data_offset;
    stream_data.data_len = segment->data_len;
    stream_data.data_offset = segment->data_offset;
    stream_data.rcv_missing_bytes = rcv_miss_len;
    stream_data.snd_missing_bytes = snd_miss_len;
    stream_data.timestamp = segment->timestamp;
    stream_data.is_forward = to_server;
    tcp_stream_rcv_data(stream, stream_data);
    snd->seq = segment->seq + (uint32_t)segment->data_len;

    delete segment;
    snd->seg_list.pop_front();
    snd->seg_num--;
    m_stat.pkt_cache_num--;

    if (stream->client.seg_list.empty() && stream->server.seg_list.empty()) {
        stream->cache_flag = false;
    } else {
        flush_cached_tcp_segment(stream);
    }
}

void TcpPacketHandler::del_all_cached_segment(tcp_stream_sptr stream)
{
    while (stream->client.seg_num + stream->server.seg_num > 0) {
        del_one_cached_segment(stream);
    }
}

tcp_stream_sptr TcpPacketHandler::get_tcp_stream(tcp_stream_id_t &id)
{
    auto mapIter = m_tcp_stream_map.find(id);
    if (mapIter == m_tcp_stream_map.end()) {
        return NULL;
    }

    // 刷新时间
    tcp_stream_sptr stream = mapIter->second.second;
    stream->update_time = SessionTimer::get_tick();
    tcp_stream_list *list = &m_tcp_stream_list;
    if (mapIter->second.first != list->begin()) {
        list->erase(mapIter->second.first);
        mapIter->second.first = list->insert(list->begin(), stream);
    }
    return stream;
}

// 新建一个tcp连接
tcp_stream_sptr TcpPacketHandler::add_tcp_stream(tcp_stream_id_t &id, tcphdr *hdr, packet_meta_t *meta)
{
    if (m_stat.stream_cur_num >= m_cfg.max_stream_num) {
        m_stat.stream_over_spec_num++;
        del_oldest_tcp_stream();
    }
    tcp_stream_sptr stream(new tcp_stream_t);
    if (stream == nullptr) {
        return nullptr;
    }
    init_tcp_stream(stream, id, hdr, meta);

    // 添加到list和map中
    tcp_stream_list *list = &m_tcp_stream_list;
    auto listIter = list->insert(list->begin(), stream); // 添加到头部
    tcp_stream_map_value_pair value_pair(listIter, stream);
    m_tcp_stream_map.insert(std::make_pair(id, value_pair));
    m_stat.stream_cur_num++;
    m_stat.stream_total_num++;

    LOG_TRACE("Add tcp connection[source:{} vlanid:{} sip:{} sport:{} dip:{} dport:{}]! Total connection num:{}",
              id.source, id.vlanid, id.sip.toString(), id.sport, id.dip.toString(), id.dport, m_tcp_stream_map.size());
    return stream;
}

// 初始化tcp连接，创建tcp连接时调用
void TcpPacketHandler::init_tcp_stream(tcp_stream_sptr stream, tcp_stream_id_t &id, tcphdr *hdr, packet_meta_t *meta)
{
    stream->id = id;
    stream->status = TCP_STREAM_INIT;
    stream->update_time = SessionTimer::get_tick();
    stream->reversed = false;
    stream->cache_flag = 0;
    stream->rcv_syn = false;
    stream->session = nullptr;
    stream->statistic.clear();
    tcp_stream_add_timer(stream);

    // 初始化connInfo 和 half stream
    tcp_hstream_t *rcv, *snd;
    if (meta->direction == PKT_DIRECTION_CLIENT_TO_SERVER) {
        stream->smac = meta->smac;
        stream->dmac = meta->dmac;
        stream->out_sip = meta->out_sip;
        stream->out_dip = meta->out_dip;
        snd = &stream->client;
        rcv = &stream->server;
    } else { // meta->direction == PKT_DIRECTION_SERVER_TO_CLIENT
        stream->smac = meta->dmac;
        stream->dmac = meta->smac;
        stream->out_sip = meta->out_dip;
        stream->out_dip = meta->out_sip;
        snd = &stream->server;
        rcv = &stream->client;
    }
    stream->client.to_server = true;
    stream->server.to_server = false;
    stream->start_time = meta->timestamp;
    stream->in_tunnel = bool(meta->in_tunnel);

    if (hdr->synFlag) {
        if (hdr->ackFlag == 0) { // syn 报文建的连接
            if (meta->hit_server == 0 && meta->direction == PKT_DIRECTION_SERVER_TO_CLIENT) {
                stream->reversed = true;
            }
            snd->seq = be32toh(hdr->sequenceNumber) + 1;
            snd->state = TCP_HALF_STREAM_SYN_SENT;
        } else { // syn-ack 报文建立连接，前面的syn报文丢失
            if (meta->hit_server == 0 && meta->direction == PKT_DIRECTION_CLIENT_TO_SERVER) {
                stream->reversed = true;
            }
            snd->seq = be32toh(hdr->sequenceNumber) + 1;
            rcv->seq = be32toh(hdr->ackNumber);
            snd->state = rcv->state = TCP_HALF_STREAM_ESTABLISHED;
            stream->status = TCP_STREAM_ESTABLISHED;
        }
        m_stat.stream_syn_create_num++;
        stream->rcv_syn = true;
        tcp_stream_rcv_ctrl_pkt(stream, hdr, meta);
    } else { // 数据报文建的连接
        if (m_cfg.work_mode == TCP_REASSEMBLY_MODE_FAST) {
            snd->seq = be32toh(hdr->sequenceNumber);
            rcv->seq = be32toh(hdr->ackNumber);
            snd->state = rcv->state = TCP_HALF_STREAM_ESTABLISHED;
            stream->status = TCP_STREAM_ESTABLISHED;
        } else {
            snd->state = rcv->state = TCP_HALF_STREAM_PRE_ESTABLISHED;
        }
        m_stat.stream_data_create_num++;
    }

    if (m_cfg.pkt_reassemble_enable == false) { // 如果重组功能没有开启，状态直接切换到establish
        snd->state = rcv->state = TCP_HALF_STREAM_ESTABLISHED;
        stream->status = TCP_STREAM_ESTABLISHED;
    }

    if (stream->status == TCP_STREAM_ESTABLISHED) {
        tcp_stream_start(stream);
    }
}

void TcpPacketHandler::del_tcp_stream(tcp_stream_id_t &id, uint32_t reason)
{
    auto mapIter = m_tcp_stream_map.find(id);
    if (mapIter == m_tcp_stream_map.end()) {
        LOG_ERROR("Delete tcp connection failed!. Can't find tcp connection[source:{} vlanid:{} sip:{} sport:{} dip:{} "
                  "dport:{}]!", id.source, id.vlanid, id.sip.toString(), id.sport, id.dip.toString(), id.dport);
        return;
    }

    tcp_stream_sptr stream = mapIter->second.second;
    if (stream->client.seg_num + stream->server.seg_num > 0) {
        del_all_cached_segment(stream);
    }

    auto listIter = mapIter->second.first;
    if (stream->status == TCP_STREAM_ESTABLISHED) {
        tcp_stream_end(stream, reason);
    }

    // 删除定时器
    if (reason != TCP_STREAM_CLOSE_TIMEOUT) {
        session_timer_del_timer(stream->timer_node);
    }

    // 释放Tcp 连接内存,使用了shared_ptr 不需要显示释放
    // if (stream != NULL) {
    //     delete stream;
    // }

    // 从map中删除
    m_tcp_stream_map.erase(mapIter);

    // 从老化链中删除
    m_tcp_stream_list.erase(listIter);
    m_stat.stream_cur_num--;
    m_stat.stream_close_num[reason]++;
    LOG_TRACE("Delete tcp connection[source:{} vlanid:{} sip:{} sport:{} dip:{} dport:{}]! Total connection num:{}",
              id.source, id.vlanid, id.sip.toString(), id.sport, id.dip.toString(), id.dport, m_tcp_stream_map.size());
}

void TcpPacketHandler::del_all_tcp_streams()
{
    if (m_tcp_stream_map.empty()) {
        return;
    }
    while (!m_tcp_stream_map.empty()) {
        auto it = m_tcp_stream_map.begin();
        tcp_stream_sptr conn = it->second.second;
        del_tcp_stream(conn->id, TCP_STREAM_CLOSE_MANUALLY);
    }
}

void TcpPacketHandler::del_oldest_tcp_stream()
{
    if (m_tcp_stream_map.empty()) {
        LOG_ERROR("Tcp connection map is empty when delete oldest tcp connection!");
        return;
    }

    if (m_tcp_stream_list.empty()) {
        return;
    }

    tcp_stream_sptr stream = m_tcp_stream_list.back();
    del_tcp_stream(stream->id, TCP_STREAM_CLOSE_OVERFLOW);
}

void TcpPacketHandler::aging_proc()
{
    uint32_t count = 0;
    do {
        if (session_timer_check_timer() == false) {
            return;
        }
        count++;
    } while (count < m_cfg.aging_proc_once_num);
}

void TcpPacketHandler::tcp_stream_timer_proc(const session_timer_node_t &node)
{
    tcp_stream_sptr stream = std::static_pointer_cast<tcp_stream_t>(node.arg);
    if (node.id != stream->timer_node.id) {
        LOG_ERROR("timer proc error.");
        return;
    }

    //  超时处理
    time_t now = SessionTimer::get_tick();
    // 1. stream timeout
    if (stream->update_time + m_cfg.stream_timeout <= now) {
        del_tcp_stream(stream->id, TCP_STREAM_CLOSE_TIMEOUT);
        return;
    }

    // 2. stream cached segment timeout
    if ((stream->cache_flag) && (stream->update_time + m_cfg.seg_cache_timeout <= now)) {
        del_all_cached_segment(stream);
    }

    // 3. 添加新的定时器
    tcp_stream_add_timer(stream);
}

void TcpPacketHandler::tcp_stream_add_timer(tcp_stream_sptr stream)
{
    time_t timeout = m_cfg.stream_timeout;
    time_t now = SessionTimer::get_tick();
    time_t gap = 0;

    if ((stream->cache_flag) && (m_cfg.seg_cache_timeout < m_cfg.stream_timeout)) {
        timeout = m_cfg.seg_cache_timeout;
    }

    if (timeout + stream->update_time - now >= 0) {
        gap = timeout + stream->update_time - now;
    } else {
        gap = timeout;
    }

    stream->timer_node = session_timer_add_timer(
        gap, [this](const struct session_timer_node &node) { this->tcp_stream_timer_proc(node); }, stream);
}

void TcpPacketHandler::tcp_stream_update_timer(tcp_stream_sptr stream)
{
    session_timer_del_timer(stream->timer_node);
    tcp_stream_add_timer(stream);
}

void TcpPacketHandler::tcp_stream_rcv_data(tcp_stream_sptr stream, const tcp_stream_data_t &stream_data)
{
    if (m_tcp_event_cb.tcp_conn_event_rcv_data == nullptr) {
        return;
    }
    m_tcp_event_cb.tcp_conn_event_rcv_data(stream, &stream_data, stream->session, m_user_data);

    m_stat.pkt_submit_num++;
    m_stat.pkt_submit_bytes += stream_data.data_len;
    m_stat.pkt_submit_missing_bytes += stream_data.snd_missing_bytes;
    m_stat.pkt_submit_missing_bytes += stream_data.rcv_missing_bytes;
    stream->statistic.pkt_submit_num++;
    stream->statistic.pkt_submit_bytes += stream_data.data_len;
    stream->statistic.pkt_submit_missing_bytes += stream_data.snd_missing_bytes;
    stream->statistic.pkt_submit_missing_bytes += stream_data.rcv_missing_bytes;

    if (stream_data.is_forward) {
        LOG_TRACE("Tcp stream rcv data ! {}:{} --> {}:{}, data seq:{} datalen:{} "
                  "send missing bytes:{} receive missing bytes:{}",
                  stream->get_sip().toString(), stream->get_sport(), stream->get_dip().toString(), stream->get_dport(),
                  stream->client.seq, stream_data.data_len, stream_data.snd_missing_bytes,
                  stream_data.rcv_missing_bytes);
    } else {
        LOG_TRACE("Tcp stream rcv data! {}:{} --> {}:{}, data seq:{} datalen:{} "
                  "send missing bytes:{} receive missing bytes:{}",
                  stream->get_dip().toString(), stream->get_dport(), stream->get_sip().toString(), stream->get_sport(),
                  stream->server.seq, stream_data.data_len, stream_data.snd_missing_bytes,
                  stream_data.rcv_missing_bytes);
    }
}

void TcpPacketHandler::tcp_stream_rcv_ctrl_pkt(tcp_stream_sptr stream, tcphdr *hdr, packet_meta_t *meta)
{
    if (m_tcp_event_cb.tcp_conn_event_rcv_ctrl_pkt == nullptr) {
        return;
    }

    tcp_stream_data_t stream_data;
    uint16_t hdr_len = uint16_t(hdr->dataOffset * 4);
    stream_data.data = (uint8_t *)hdr + hdr_len;
    stream_data.data_offset = meta->l4_offset - meta->ip_offset + hdr_len;

    m_tcp_event_cb.tcp_conn_event_rcv_ctrl_pkt(stream, &stream_data, stream->session, m_user_data);
    LOG_DEBUG("Tcp stream rcv ctrl pkt, flag:[syn:{}, ack:{}]! [sip:{} sport:{} dip:{} dport:{}]", hdr->synFlag,
              hdr->ackFlag, meta->sip.toString(), meta->sport, meta->dip.toString(), meta->dport);
}

void TcpPacketHandler::tcp_stream_start(tcp_stream_sptr stream)
{
    if (m_tcp_event_cb.tcp_conn_event_start == nullptr) {
        return;
    }

    stream->session = m_tcp_event_cb.tcp_conn_event_start(stream, m_user_data);
    LOG_TRACE("Tcp stream start! [sip:{} sport:{} dip:{} dport:{} timestamp:{}]", stream->id.sip.toString(),
              stream->id.sport, stream->id.dip.toString(), stream->id.dport, stream->start_time.tv_sec);
}

void TcpPacketHandler::tcp_stream_end(tcp_stream_sptr stream, uint32_t reason)
{
    if (m_tcp_event_cb.tcp_conn_event_end == nullptr) {
        return;
    }

    m_tcp_event_cb.tcp_conn_event_end(stream, reason, stream->session, m_user_data);
    stream->session = nullptr;
    LOG_TRACE("Tcp stream end! [sip:{} sport:{} dip:{} dport:{} timestamp:{}]", stream->id.sip.toString(),
              stream->id.sport, stream->id.dip.toString(), stream->id.dport, stream->end_time.tv_sec);
}

void TcpPacketHandler::printTcpStreamCount()
{
    std::cout << "TCP stream total count:" << m_stat.stream_total_num << std::endl;
    std::cout << "TCP stream create by syn count:" << m_stat.stream_syn_create_num << std::endl;
    std::cout << "TCP stream create by data count:" << m_stat.stream_data_create_num << std::endl;
    std::cout << "TCP stream over flow count:" << m_stat.stream_over_spec_num << std::endl;
    std::cout << "TCP stream closed by fin count:" << m_stat.stream_close_num[TCP_STREAM_CLOSE_FIN] << std::endl;
    std::cout << "TCP stream closed by rst count:" << m_stat.stream_close_num[TCP_STREAM_CLOSE_RST] << std::endl;
    std::cout << "TCP stream closed by timeout count:" << m_stat.stream_close_num[TCP_STREAM_CLOSE_TIMEOUT] << std::endl;
    std::cout << "TCP stream closed by manually count:" << m_stat.stream_close_num[TCP_STREAM_CLOSE_MANUALLY]
              << std::endl;
    std::cout << "TCP stream closed by overflow count:" << m_stat.stream_close_num[TCP_STREAM_CLOSE_OVERFLOW]
              << std::endl;
    std::cout << "TCP stream open count:" << m_stat.stream_cur_num << std::endl;
}

void TcpPacketHandler::printTcpPktCount(tcp_statistic_t &stat)
{
    std::cout << "TCP packet receive count:" << stat.pkt_rcv_num << std::endl;
    std::cout << "TCP packet receive bytes:" << stat.pkt_rcv_data_bytes << std::endl;
    std::cout << "TCP syn count:" << stat.pkt_syn_num << std::endl;
    std::cout << "TCP reset count:" << stat.pkt_rst_num << std::endl;
    std::cout << "TCP fin count:" << stat.pkt_fin_num << std::endl;
    std::cout << "TCP no data ack count:" << stat.pkt_no_data_num << std::endl;
    std::cout << "TCP submit count:" << stat.pkt_submit_num << std::endl;
    std::cout << "TCP submit data bytes:" << stat.pkt_submit_bytes << std::endl;

    // 乱序
    std::cout << "TCP in order packet count:" << stat.pkt_in_order_num << std::endl;
    std::cout << "TCP out of order packet count:" << stat.pkt_ooo_num << std::endl;
    std::cout << "TCP out of order packet count(two way):" << stat.pkt_two_way_ooo_num << std::endl;

    // 丢包
    std::cout << "TCP packet drop count:" << stat.pkt_drop_num << std::endl;
    std::cout << "Not TCP packet count:" << stat.pkt_not_tcp_num << std::endl;
    std::cout << "Not server packet count:" << stat.pkt_not_server_num << std::endl;
    std::cout << "retransmit packet count:" << stat.pkt_rtns_num << std::endl;
}

void TcpPacketHandler::printTcpStreamPktCount(tcp_statistic_t &stat)
{
    std::cout << "TCP packet receive count:" << stat.pkt_rcv_num << std::endl;
    std::cout << "TCP packet receive bytes:" << stat.pkt_rcv_data_bytes << std::endl;
    std::cout << "TCP syn count:" << stat.pkt_syn_num << std::endl;
    std::cout << "TCP fin count:" << stat.pkt_fin_num << std::endl;
    std::cout << "TCP submit count:" << stat.pkt_submit_num << std::endl;
    std::cout << "TCP submit data bytes:" << stat.pkt_submit_bytes << std::endl;

    // 乱序
    std::cout << "TCP in order packet count:" << stat.pkt_in_order_num << std::endl;
    std::cout << "TCP out of order packet count:" << stat.pkt_ooo_num << std::endl;
    std::cout << "TCP out of order packet count(two way):" << stat.pkt_two_way_ooo_num << std::endl;

    // 丢包
    std::cout << "TCP packet drop count:" << stat.pkt_drop_num << std::endl;
    std::cout << "retransmit packet count:" << stat.pkt_rtns_num << std::endl;
}

void TcpPacketHandler::printTcpStream(tcp_stream_sptr stream)
{
    std::cout << std::endl;
    std::cout << "Tcp stream ID[source:" << stream->id.source << " vlanid:" << stream->id.vlanid
              << "srcIP:" << stream->id.sip.toString() << " srcPort:" << stream->id.sport
              << " dstIP:" << stream->id.dip.toString() << " dstPort:" << stream->id.dport << "]" << std::endl;
    std::cout << "Conn state:" << stream->status << " client state:" << stream->client.state
              << " server state:" << stream->server.state << std::endl;
    std::cout << "client seq:" << stream->client.seq << " server seq:" << stream->server.seq;
    printTcpStreamPktCount(stream->statistic);
    std::cout << std::endl;
}

void TcpPacketHandler::printCurTcpStreamMap()
{
    std::cout << "Current tcp connection num:" << m_stat.stream_cur_num << std::endl;
    auto iter = m_tcp_stream_map.begin();
    while (iter != m_tcp_stream_map.end()) {
        tcp_stream_sptr stream = iter->second.second;
        printTcpStream(stream);
        iter++;
    }
}

void TcpPacketHandler::print_tcp_stream_statistic()
{
    // 1. tcp stream 整体统计
    printTcpStreamCount();

    // 2. 报文整体统计
    printTcpPktCount(m_stat);

    // 3. 当前 tcp stream具体信息
    printCurTcpStreamMap();
}

} // namespace secsmart_tcpip
